// Scripts/Core/GridManager.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GridManager : MonoBehaviour
{
    [Header("网格设置")]
    public float cellSize = 100f;
    public float spacing = 5f;
    public Vector2 gridOffset = Vector2.zero;
    
    [Header("预制体")]
    public GameObject tilePrefab;
    
    // 网格数据
    private Tile[,] grid;
    private int width, height;
    private Vector2 startPosition;
    
    // 选择状态
    private Tile selectedTile;
    private bool isSwapping = false;
    private bool isProcessing = false;
    private Color originalTileColor;
    
    public void InitializeGrid(int gridWidth, int gridHeight)
    {
        width = gridWidth;
        height = gridHeight;
        grid = new Tile[width, height];
        
        CalculateGridLayout();
        CreateInitialGrid();
        StartCoroutine(CheckInitialMatches());
    }
    
    void CalculateGridLayout()
    {
        // 计算网格总尺寸
        float totalWidth = width * cellSize + (width - 1) * spacing;
        float totalHeight = height * cellSize + (height - 1) * spacing;
        
        // 计算网格起始位置（使网格居中）
        // GridManager对象已经通过RectTransform居中，所以我们计算相对于中心的偏移
        startPosition = new Vector2(
            -totalWidth / 2 + cellSize / 2,    // X: 从网格左边开始，相对于中心
            totalHeight / 2 - cellSize / 2     // Y: 从网格顶部开始，相对于中心
        ) + gridOffset;
    }
    
    void CreateInitialGrid()
    {
        for (int y = 0; y < height; y++)
        {
            for (int x = 0; x < width; x++)
            {
                CreateTile(x, y, true);
            }
        }
    }
    
    void CreateTile(int x, int y, bool avoidInitialMatches = false)
    {
        Vector3 position = GetWorldPosition(x, y);
        GameObject tileObj = Instantiate(tilePrefab, transform);
        
        // 对于UI元素，需要设置RectTransform的anchoredPosition
        RectTransform rectTransform = tileObj.GetComponent<RectTransform>();
        rectTransform.anchoredPosition = position;
        
        Tile tile = tileObj.GetComponent<Tile>();
        tile.Initialize(x, y, GetRandomTileType(avoidInitialMatches ? GetAvoidTypes(x, y) : null));
        
        grid[x, y] = tile;
        tile.name = $"Tile_{x}_{y}";
    }
    
    int GetRandomTileType(List<int> avoidTypes = null)
    {
        int type;
        int attempts = 0;
        
        do
        {
            type = Random.Range(0, 5); // 5种类型
            attempts++;
        }
        while (avoidTypes != null && avoidTypes.Contains(type) && attempts < 10);
        
        return type;
    }
    
    List<int> GetAvoidTypes(int x, int y)
    {
        List<int> avoidTypes = new List<int>();
        
        // 避免初始时就有匹配
        if (x >= 2)
        {
            if (grid[x-1, y] != null && grid[x-2, y] != null && 
                grid[x-1, y].tileType == grid[x-2, y].tileType)
            {
                avoidTypes.Add(grid[x-1, y].tileType);
            }
        }
        
        if (y >= 2)
        {
            if (grid[x, y-1] != null && grid[x, y-2] != null && 
                grid[x, y-1].tileType == grid[x, y-2].tileType)
            {
                avoidTypes.Add(grid[x, y-1].tileType);
            }
        }
        
        return avoidTypes;
    }
    
    IEnumerator CheckInitialMatches()
    {
        // 等待一帧确保所有Tile都已创建
        yield return null;
    
        List<Tile> initialMatches = FindMatches();
        int attemptCount = 0;
        const int maxAttempts = 10; // 防止无限循环
    
        // 如果有初始匹配，重新生成这些Tile
        while (initialMatches.Count > 0 && attemptCount < maxAttempts)
        {
            Debug.Log($"发现初始匹配，尝试重新生成 ({attemptCount + 1}/{maxAttempts})");
        
            // 重新生成匹配的Tile
            foreach (Tile matchedTile in initialMatches)
            {
                int x = matchedTile.gridX;
                int y = matchedTile.gridY;
            
                // 销毁旧的Tile
                if (grid[x, y] != null)
                {
                    Destroy(grid[x, y].gameObject);
                    grid[x, y] = null;
                }
            
                // 创建新的Tile（避免同样的类型）
                CreateTile(x, y, true);
            }
        
            // 等待一帧让新Tile生成
            yield return null;
        
            // 再次检查匹配
            initialMatches = FindMatches();
            attemptCount++;
        }
    
        if (attemptCount >= maxAttempts)
        {
            Debug.LogWarning("达到最大尝试次数，可能无法完全消除初始匹配");
        }
        else
        {
            Debug.Log("初始网格检查完成，无匹配");
        }
    
        // 确保所有Tile都正确初始化
        ValidateGrid();
        
        // 设置Tile事件监听
        SetupTileEvents();
    }

    void ValidateGrid()
    {
        for (int x = 0; x < width; x++)
        {
            for (int y = 0; y < height; y++)
            {
                if (grid[x, y] == null)
                {
                    Debug.LogError($"网格位置 ({x}, {y}) 为空！");
                    CreateTile(x, y, false);
                }
                else if (grid[x, y].isEmpty)
                {
                    Debug.LogError($"网格位置 ({x}, {y}) 的Tile被标记为空！");
                    grid[x, y].isEmpty = false;
                }
            }
        }
    }
    
    /// <summary>
    /// 获取指定网格位置的世界坐标
    /// </summary>
    public Vector3 GetWorldPosition(int x, int y)
    {
        return startPosition + new Vector2(
            x * (cellSize + spacing),
            -y * (cellSize + spacing)  // Y轴向下为正，符合网格从上到下的布局
        );
    }
    
    // 查找匹配的Tile
    public List<Tile> FindMatches()
    {
        List<Tile> matches = new List<Tile>();
        
        // 检查水平匹配
        for (int y = 0; y < height; y++)
        {
            for (int x = 0; x < width - 2; x++)
            {
                if (grid[x, y] != null && grid[x + 1, y] != null && grid[x + 2, y] != null &&
                    !grid[x, y].isEmpty && !grid[x + 1, y].isEmpty && !grid[x + 2, y].isEmpty)
                {
                    if (grid[x, y].tileType == grid[x + 1, y].tileType && 
                        grid[x + 1, y].tileType == grid[x + 2, y].tileType)
                    {
                        // 找到3个或更多连续的匹配
                        List<Tile> horizontalMatch = new List<Tile>();
                        horizontalMatch.Add(grid[x, y]);
                        horizontalMatch.Add(grid[x + 1, y]);
                        horizontalMatch.Add(grid[x + 2, y]);
                        
                        // 检查是否有更多连续的
                        int checkX = x + 3;
                        while (checkX < width && grid[checkX, y] != null && 
                               !grid[checkX, y].isEmpty && 
                               grid[checkX, y].tileType == grid[x, y].tileType)
                        {
                            horizontalMatch.Add(grid[checkX, y]);
                            checkX++;
                        }
                        
                        // 添加到匹配列表（避免重复）
                        foreach (Tile tile in horizontalMatch)
                        {
                            if (!matches.Contains(tile))
                            {
                                matches.Add(tile);
                            }
                        }
                    }
                }
            }
        }
        
        // 检查垂直匹配
        for (int x = 0; x < width; x++)
        {
            for (int y = 0; y < height - 2; y++)
            {
                if (grid[x, y] != null && grid[x, y + 1] != null && grid[x, y + 2] != null &&
                    !grid[x, y].isEmpty && !grid[x, y + 1].isEmpty && !grid[x, y + 2].isEmpty)
                {
                    if (grid[x, y].tileType == grid[x, y + 1].tileType && 
                        grid[x, y + 1].tileType == grid[x, y + 2].tileType)
                    {
                        // 找到3个或更多连续的匹配
                        List<Tile> verticalMatch = new List<Tile>();
                        verticalMatch.Add(grid[x, y]);
                        verticalMatch.Add(grid[x, y + 1]);
                        verticalMatch.Add(grid[x, y + 2]);
                        
                        // 检查是否有更多连续的
                        int checkY = y + 3;
                        while (checkY < height && grid[x, checkY] != null && 
                               !grid[x, checkY].isEmpty && 
                               grid[x, checkY].tileType == grid[x, y].tileType)
                        {
                            verticalMatch.Add(grid[x, checkY]);
                            checkY++;
                        }
                        
                        // 添加到匹配列表（避免重复）
                        foreach (Tile tile in verticalMatch)
                        {
                            if (!matches.Contains(tile))
                            {
                                matches.Add(tile);
                            }
                        }
                    }
                }
            }
        }
        
        return matches;
    }
    
    // 处理Tile选择
    public void OnTileSelected(Tile tile)
    {
        // 只在交换模式下处理瓦片选择
        if (isProcessing || !GameManager.Instance.CanMakeMove() || 
            GameManager.Instance.GetCurrentGameMode() != GameMode.SwapMode) 
            return;
        
        if (selectedTile == null)
        {
            // 第一次选择
            selectedTile = tile;
            HighlightTile(tile, true);
        }
        else if (selectedTile == tile)
        {
            // 取消选择
            HighlightTile(selectedTile, false);
            selectedTile = null;
        }
        else
        {
            // 尝试交换
            if (AreAdjacent(selectedTile, tile))
            {
                StartCoroutine(HandleTileSwap(selectedTile, tile));
            }
            else
            {
                // 选择新的Tile
                HighlightTile(selectedTile, false);
                selectedTile = tile;
                HighlightTile(tile, true);
            }
        }
    }
    
    // 检查两个Tile是否相邻
    bool AreAdjacent(Tile tile1, Tile tile2)
    {
        int deltaX = Mathf.Abs(tile1.gridX - tile2.gridX);
        int deltaY = Mathf.Abs(tile1.gridY - tile2.gridY);
        
        return (deltaX == 1 && deltaY == 0) || (deltaX == 0 && deltaY == 1);
    }
    
    // 高亮显示Tile
    void HighlightTile(Tile tile, bool highlight)
    {
        if (tile != null && tile.tileImage != null)
        {
            if (highlight)
            {
                originalTileColor = tile.tileImage.color;
                tile.tileImage.color = Color.white;
            }
            else
            {
                tile.UpdateVisuals(); // 恢复原始颜色
            }
        }
    }
    
    // 处理Tile交换
    IEnumerator HandleTileSwap(Tile tile1, Tile tile2)
    {
        isSwapping = true;
        isProcessing = true;
        
        // 取消高亮
        HighlightTile(tile1, false);
        HighlightTile(tile2, false);
        
        // 执行带动画的交换
        yield return StartCoroutine(SwapTilesWithAnimation(tile1, tile2, 0.3f));
        
        // 检查是否有匹配
        List<Tile> matches = FindMatches();
        
        if (matches.Count > 0)
        {
            // 有效交换，消耗移动次数
            GameManager.Instance.UseMove();
            
            // 处理匹配
            yield return StartCoroutine(ProcessMatches());
        }
        else
        {
            // 无效交换，恢复原位（也使用动画）
            yield return StartCoroutine(SwapTilesWithAnimation(tile1, tile2, 0.3f));
        }
        
        selectedTile = null;
        isSwapping = false;
        isProcessing = false;
    }
    
    // 交换两个Tile的位置和数据（无动画，立即交换）
    void SwapTiles(Tile tile1, Tile tile2)
    {
        // 交换网格位置
        int tempX = tile1.gridX;
        int tempY = tile1.gridY;
        
        tile1.gridX = tile2.gridX;
        tile1.gridY = tile2.gridY;
        tile2.gridX = tempX;
        tile2.gridY = tempY;
        
        // 更新网格数组
        grid[tile1.gridX, tile1.gridY] = tile1;
        grid[tile2.gridX, tile2.gridY] = tile2;
        
        // 更新UI位置（立即设置，无动画）
        RectTransform rect1 = tile1.GetComponent<RectTransform>();
        RectTransform rect2 = tile2.GetComponent<RectTransform>();
        rect1.anchoredPosition = GetWorldPosition(tile1.gridX, tile1.gridY);
        rect2.anchoredPosition = GetWorldPosition(tile2.gridX, tile2.gridY);
        
        // 更新名称
        tile1.name = $"Tile_{tile1.gridX}_{tile1.gridY}";
        tile2.name = $"Tile_{tile2.gridX}_{tile2.gridY}";
    }
    
    // 带动画的瓦片交换
    IEnumerator SwapTilesWithAnimation(Tile tile1, Tile tile2, float duration = 0.3f)
    {
        // 获取起始位置
        Vector2 startPos1 = tile1.GetComponent<RectTransform>().anchoredPosition;
        Vector2 startPos2 = tile2.GetComponent<RectTransform>().anchoredPosition;
        
        // 交换网格位置数据
        int tempX = tile1.gridX;
        int tempY = tile1.gridY;
        
        tile1.gridX = tile2.gridX;
        tile1.gridY = tile2.gridY;
        tile2.gridX = tempX;
        tile2.gridY = tempY;
        
        // 更新网格数组
        grid[tile1.gridX, tile1.gridY] = tile1;
        grid[tile2.gridX, tile2.gridY] = tile2;
        
        // 获取目标位置
        Vector2 targetPos1 = GetWorldPosition(tile1.gridX, tile1.gridY);
        Vector2 targetPos2 = GetWorldPosition(tile2.gridX, tile2.gridY);
        
        // 获取RectTransform组件
        RectTransform rect1 = tile1.GetComponent<RectTransform>();
        RectTransform rect2 = tile2.GetComponent<RectTransform>();
        
        // 执行动画
        float elapsed = 0f;
        while (elapsed < duration)
        {
            elapsed += Time.deltaTime;
            float t = elapsed / duration;
            
            // 使用平滑插值
            float smoothT = Mathf.SmoothStep(0f, 1f, t);
            
            // 同时移动两个瓦片
            rect1.anchoredPosition = Vector2.Lerp(startPos1, targetPos1, smoothT);
            rect2.anchoredPosition = Vector2.Lerp(startPos2, targetPos2, smoothT);
            
            yield return null;
        }
        
        // 确保最终位置准确
        rect1.anchoredPosition = targetPos1;
        rect2.anchoredPosition = targetPos2;
        
        // 更新名称
        tile1.name = $"Tile_{tile1.gridX}_{tile1.gridY}";
        tile2.name = $"Tile_{tile2.gridX}_{tile2.gridY}";
    }
    
    // 处理匹配消除
    IEnumerator ProcessMatches()
    {
        List<Tile> allMatches = FindMatches();
        
        while (allMatches.Count > 0)
        {
            // 标记匹配的Tile
            foreach (Tile tile in allMatches)
            {
                tile.SetMatched(true);
            }
            
            // 计算分数
            int score = allMatches.Count * 10;
            GameManager.Instance.AddScore(score);
            
            // 等待匹配动画
            yield return new WaitForSeconds(0.5f);
            
            // 清除匹配的Tile
            foreach (Tile tile in allMatches)
            {
                tile.Clear();
            }
            
            // 等待清除动画
            yield return new WaitForSeconds(0.3f);
            
            // 应用重力
            yield return StartCoroutine(ApplyGravity());
            
            // 填充空位
            yield return StartCoroutine(FillEmptySpaces());
            
            // 检查新的匹配（连锁反应）
            allMatches = FindMatches();
        }
    }
    
    // 应用重力，让Tile下落
    IEnumerator ApplyGravity()
    {
        bool hasMovement = true;
        
        while (hasMovement)
        {
            hasMovement = false;
            
            for (int x = 0; x < width; x++)
            {
                for (int y = height - 2; y >= 0; y--)
                {
                    if (grid[x, y] != null && !grid[x, y].isEmpty)
                    {
                        // 查找下方最近的空位
                        int targetY = y;
                        for (int checkY = y + 1; checkY < height; checkY++)
                        {
                            if (grid[x, checkY] == null || grid[x, checkY].isEmpty)
                            {
                                targetY = checkY;
                            }
                            else
                            {
                                break;
                            }
                        }
                        
                        // 如果需要移动
                        if (targetY != y)
                        {
                            Tile movingTile = grid[x, y];
                            
                            // 清空原位置
                            grid[x, y] = null;
                            
                            // 更新Tile位置
                            movingTile.gridX = x;
                            movingTile.gridY = targetY;
                            RectTransform rectTransform = movingTile.GetComponent<RectTransform>();
                            rectTransform.anchoredPosition = GetWorldPosition(x, targetY);
                            movingTile.name = $"Tile_{x}_{targetY}";
                            
                            // 设置新位置
                            if (grid[x, targetY] != null)
                            {
                                Destroy(grid[x, targetY].gameObject);
                            }
                            grid[x, targetY] = movingTile;
                            
                            hasMovement = true;
                        }
                    }
                }
            }
            
            if (hasMovement)
            {
                yield return new WaitForSeconds(0.1f);
            }
        }
    }
    
    // 填充空位
    IEnumerator FillEmptySpaces()
    {
        for (int x = 0; x < width; x++)
        {
            for (int y = 0; y < height; y++)
            {
                if (grid[x, y] == null || grid[x, y].isEmpty)
                {
                    // 销毁空的Tile对象
                    if (grid[x, y] != null)
                    {
                        Destroy(grid[x, y].gameObject);
                    }
                    
                    // 创建新的Tile
                    CreateTile(x, y, false);
                    
                    // 为新Tile添加事件监听
                    grid[x, y].OnTileSelected += OnTileSelected;
                    
                    // 设置初始位置在屏幕上方
                    Vector3 startPos = GetWorldPosition(x, -1);
                    RectTransform newTileRect = grid[x, y].GetComponent<RectTransform>();
                    newTileRect.anchoredPosition = startPos;
                    
                    // 动画移动到目标位置
                    Vector3 targetPos = GetWorldPosition(x, y);
                    StartCoroutine(MoveTileToPosition(grid[x, y], targetPos));
                }
            }
        }
        
        yield return new WaitForSeconds(0.5f);
    }
    
    /// <summary>
    /// 移动Tile到指定位置 (供其他模式使用)
    /// </summary>
    public IEnumerator MoveTileToPosition(Tile tile, Vector3 targetPosition)
    {
        float duration = 0.3f;
        float elapsed = 0f;
        RectTransform rectTransform = tile.GetComponent<RectTransform>();
        Vector2 startPosition = rectTransform.anchoredPosition;
        
        while (elapsed < duration)
        {
            elapsed += Time.deltaTime;
            float t = elapsed / duration;
            rectTransform.anchoredPosition = Vector2.Lerp(startPosition, targetPosition, t);
            yield return null;
        }
        
        rectTransform.anchoredPosition = targetPosition;
    }
    
    // 检查是否有可能的移动
    public bool CheckForPossibleMoves()
    {
        for (int x = 0; x < width; x++)
        {
            for (int y = 0; y < height; y++)
            {
                if (grid[x, y] != null && !grid[x, y].isEmpty)
                {
                    // 检查右边
                    if (x < width - 1 && grid[x + 1, y] != null && !grid[x + 1, y].isEmpty)
                    {
                        if (WouldCreateMatch(x, y, x + 1, y))
                        {
                            return true;
                        }
                    }
                    
                    // 检查下边
                    if (y < height - 1 && grid[x, y + 1] != null && !grid[x, y + 1].isEmpty)
                    {
                        if (WouldCreateMatch(x, y, x, y + 1))
                        {
                            return true;
                        }
                    }
                }
            }
        }
        
        return false;
    }
    
    // 检查交换两个位置是否会产生匹配
    bool WouldCreateMatch(int x1, int y1, int x2, int y2)
    {
        // 临时交换
        Tile tile1 = grid[x1, y1];
        Tile tile2 = grid[x2, y2];
        
        grid[x1, y1] = tile2;
        grid[x2, y2] = tile1;
        
        // 检查是否有匹配
        bool hasMatch = FindMatches().Count > 0;
        
        // 恢复原状
        grid[x1, y1] = tile1;
        grid[x2, y2] = tile2;
        
        return hasMatch;
    }
    
    // 设置Tile事件监听
    void SetupTileEvents()
    {
        for (int x = 0; x < width; x++)
        {
            for (int y = 0; y < height; y++)
            {
                if (grid[x, y] != null)
                {
                    grid[x, y].OnTileSelected += OnTileSelected;
                }
            }
        }
    }
    
    // ===== 公共访问方法 (供其他游戏模式使用) =====
    
    /// <summary>
    /// 获取网格数组的引用
    /// </summary>
    public Tile[,] GetGrid()
    {
        return grid;
    }
    
    /// <summary>
    /// 获取网格宽度
    /// </summary>
    public int GetWidth()
    {
        return width;
    }
    
    /// <summary>
    /// 获取网格高度
    /// </summary>
    public int GetHeight()
    {
        return height;
    }
    

    
    /// <summary>
    /// 创建新的瓦片 (供其他模式使用)
    /// </summary>
    public Tile CreateTile(int x, int y, int type, bool avoidInitialMatches = false)
    {
        Vector2 position = GetWorldPosition(x, y);
        GameObject tileObj = Instantiate(tilePrefab, transform);
        
        RectTransform rectTransform = tileObj.GetComponent<RectTransform>();
        rectTransform.anchoredPosition = position;
        
        Tile tile = tileObj.GetComponent<Tile>();
        
        if (avoidInitialMatches)
        {
            // 避免初始匹配的类型选择
            List<int> availableTypes = new List<int> { 0, 1, 2, 3, 4, 5 };
            
            // 检查左边的瓦片
            if (x >= 2 && grid[x-1, y] != null && grid[x-2, y] != null)
            {
                if (grid[x-1, y].tileType == grid[x-2, y].tileType)
                {
                    availableTypes.Remove(grid[x-1, y].tileType);
                }
            }
            
            // 检查上面的瓦片
            if (y >= 2 && grid[x, y-1] != null && grid[x, y-2] != null)
            {
                if (grid[x, y-1].tileType == grid[x, y-2].tileType)
                {
                    availableTypes.Remove(grid[x, y-1].tileType);
                }
            }
            
            type = availableTypes[Random.Range(0, availableTypes.Count)];
        }
        
        tile.Initialize(x, y, type);
        tile.name = $"Tile_{x}_{y}";
        
        return tile;
    }
}